package adminmodels

import (
	"fmt"
	tkcrypt "github.com/ikaiguang/srv_toolkit/crypt"
	tklog "github.com/ikaiguang/srv_toolkit/log"
	tkrandom "github.com/ikaiguang/srv_toolkit/random"
	"github.com/pkg/errors"
	"gorm.io/gorm"
	"strconv"
	"time"
)

// TableSQL : table SQL
func (m *admins) TableSQL() string {
	execSQL := `
-- 管理员表
CREATE TABLE %s
(
    id            BIGINT AUTO_INCREMENT COMMENT '管理员id',
    username      VARCHAR(32)  NOT NULL DEFAULT '' COMMENT '用户名',
    nickname      VARCHAR(64)  NOT NULL DEFAULT '' COMMENT '昵称',
    phone         CHAR(11)     NOT NULL DEFAULT '' COMMENT '手机号码',
    password      VARCHAR(255) NOT NULL DEFAULT '' COMMENT '密码',
    active_status TINYINT(1)   NOT NULL DEFAULT '0' COMMENT '激活状态；0：未激活；1：已激活；2：已禁用',
    c_uid         BIGINT       NOT NULL DEFAULT '0' COMMENT '创建用户',
    c_time        BIGINT       NOT NULL DEFAULT '0' COMMENT '创建时间',
    is_del        TINYINT(1)   NOT NULL DEFAULT '0' COMMENT '软删除',
    d_uid         BIGINT       NOT NULL DEFAULT '0' COMMENT '删除用户',
    d_time        BIGINT       NOT NULL DEFAULT '0' COMMENT '删除时间',
    m_time        BIGINT       NOT NULL DEFAULT '0' COMMENT '更新时间',
    PRIMARY KEY (id),
    UNIQUE KEY admin_username (username),
    UNIQUE KEY admin_phone (phone)
) ENGINE InnoDB
  DEFAULT CHARSET utf8mb4
    COMMENT '管理员表';
`
	return fmt.Sprintf(execSQL, m.TableName())
}

// InitWithDBConn .
func (m *admins) InitWithDBConn(dbConn *gorm.DB) (err error) {
	var (
		//username       = m.RandomUsername()
		userID   int64 = 1
		username       = "ikaiguang"
		nickname       = "管理员"
		phone          = "13800138000" // 13800138000
		password       = "github.com"  // md5(password)
	)
	// 管理员
	tklog.Info("初始化：检查管理员")
	var anotherAdminModel = &Admins{}
	err = dbConn.Table(m.TableName()).
		Where("id = ?", userID).
		First(anotherAdminModel).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			err = nil
		} else {
			return
		}
	}

	// 存在
	if anotherAdminModel.Id == userID {
		return
	}

	// 创建
	nowTime := time.Now()

	// 事务
	tx := dbConn.Begin()
	defer func() {
		if err != nil {
			deferErr := tx.Rollback().Error
			if deferErr != nil {
				tklog.ERROR(deferErr)
			}
		}
	}()

	// 管理员
	if anotherAdminModel.Id != userID {
		tklog.Info("初始化：管理员账户")
		passwordBytes, err := m.EncryptPassword(password, true)
		if err != nil {
			return errors.WithStack(err)
		}
		adminModel := &Admins{
			Id:           userID,
			Nickname:     nickname,
			Username:     username,
			Phone:        phone,
			Password:     string(passwordBytes),
			ActiveStatus: AdminActiveStatusActive,
			CUid:         userID,
			CTime:        nowTime.Unix(),
			MTime:        nowTime.Unix(),
		}
		err = tx.Create(adminModel).Error
		if err != nil {
			return errors.WithStack(err)
		}
	}

	// 提交
	if err = tx.Commit().Error; err != nil {
		err = errors.WithStack(err)
		return
	}
	return
}

// EncryptPassword .
func (m *admins) EncryptPassword(password string, md5 bool) ([]byte, error) {
	if md5 {
		password = tkcrypt.Md5(password)
	}
	return tkcrypt.PasswordEncrypt(password)
}

// ComparePassword .
func (m *admins) ComparePassword(hashedPassword, password string, md5 bool) error {
	if md5 {
		password = tkcrypt.Md5(password)
	}
	return tkcrypt.PasswordCompare(hashedPassword, password)
}

// RandomUsername .
func (m *admins) RandomUsername() string {
	return strconv.FormatInt(time.Now().UnixNano(), 36) + "_" + tkrandom.Strings(3)
}
